package ru.kradef.taxi.service;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Properties;

public class HttpResponse {
    private Socket socket;
    private Properties headers = new Properties();

    public HttpResponse(Socket socket) {
	this.socket = socket;
    }

    public void setHeader(String name, String value) {
	headers.setProperty(name, value);
    }

    public void setContentLength(int length) {
	headers.setProperty("Content-Length", String.valueOf(length));
    }

    public void setContentType(String type) {
	headers.setProperty("Content-Type", type);
    }

    public OutputStream getOutputStream() throws IOException {
	// wrap to flush headers before real writing and closing
	return new StreamWrapper(socket.getOutputStream());
    }

    public void close() {
	try {
	    flushHeaders();
	    socket.close();
	} catch (Exception e) {
	    // ignore
	}
	socket = null;
    }

    private void flushHeaders() throws IOException {
	if (headers == null || headers.isEmpty()) {
	    return;
	}
	PrintStream out = new PrintStream(socket.getOutputStream());
	// TODO: set http status as parameter
	out.print("HTTP/1.1 200 OK");
	for (String key : headers.stringPropertyNames()) {
	    out.print(key);
	    out.print(":");
	    out.print(headers.getProperty(key));
	    out.print("\r\n");
	}
	out.print("\r\n");
	headers.clear();
	headers = null;
    }

    private class StreamWrapper extends FilterOutputStream {

	@Override
	public void write(int b) throws IOException {
	    flushHeaders();
	    super.write(b);
	}

	@Override
	public void write(byte[] b) throws IOException {
	    flushHeaders();
	    super.write(b);
	}

	@Override
	public void write(byte[] b, int off, int len) throws IOException {
	    flushHeaders();
	    super.write(b, off, len);
	}

	@Override
	public void close() throws IOException {
	    flushHeaders();
	    super.close();
	}

	public StreamWrapper(OutputStream out) {
	    super(out);
	}

    }

}
